import logging
from pathlib import Path
from pydantic import BaseModel
from pysam import AlignmentFile  # pylint: disable=E0611

logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s")
logger = logging.getLogger("ClinCNV")


class Gender(BaseModel):
    bam_file: Path
    gender_file: Path
    max_female: float = 0.06
    min_male: float = 0.09

    @classmethod
    def count_reads(cls, alignment_file: AlignmentFile, chrom: str, start: int, end: int) -> int:
        count = 0
        for read in alignment_file.fetch(contig=chrom, start=start, end=end):
            if read.is_unmapped or read.is_secondary or read.is_supplementary or read.is_duplicate:
                continue
            count += 1
        return count

    def do_gender(self):
        logger.info("Do gender to %s", self.gender_file)
        x_chrom_size = min(156040895, 155270560)  # GRCh37, GRCh38
        y_chrom_size = min(57227415, 59373566)  # GRCh37, GRCh38
        with AlignmentFile(str(self.bam_file)) as alignment_file:
            x_reads = self.count_reads(alignment_file=alignment_file, chrom="chrX", start=0, end=x_chrom_size)
            y_reads = self.count_reads(alignment_file=alignment_file, chrom="chrY", start=0, end=y_chrom_size)
            ratio_yx = y_reads / x_reads
            gender = "-"
            if ratio_yx <= self.max_female:
                gender = "female"
            if ratio_yx >= self.min_male:
                gender = "male"
            self.gender_file.write_text(gender)

    def run(self):
        if not self.gender_file.exists():
            self.do_gender()
